﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Speech.Synthesis;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using UniRlv.COL;

namespace UniRlv.Utility
{
    public static class AppHelper
    {
        static SpeechSynthesizer speech = new SpeechSynthesizer();

        public static void Init()
        {
            try
            {
                CultureInfo keyboardCulture = System.Windows.Forms.InputLanguage.CurrentInputLanguage.Culture;
                InstalledVoice neededVoice = speech.GetInstalledVoices(keyboardCulture).FirstOrDefault();
                if (neededVoice == null)
                {
                    return;
                }
                else if (!neededVoice.Enabled)
                {
                    return;
                }
                else
                {
                    speech.SelectVoice(neededVoice.VoiceInfo.Name);
                }
            }
            catch (Exception)
            {

            }

        }

        #region 通用
        //压缩字节
        //1.创建压缩的数据流 
        //2.设定compressStream为存放被压缩的文件流,并设定为压缩模式
        //3.将需要压缩的字节写到被压缩的文件流
        public static byte[] CompressBytes(byte[] bytes)
        {
            using (MemoryStream compressStream = new MemoryStream())
            {
                using (var zipStream = new GZipStream(compressStream, CompressionMode.Compress))
                    zipStream.Write(bytes, 0, bytes.Length);
                return compressStream.ToArray();
            }
        }

        //解压缩字节
        //1.创建被压缩的数据流
        //2.创建zipStream对象，并传入解压的文件流
        //3.创建目标流
        //4.zipStream拷贝到目标流
        //5.返回目标流输出字节
        public static byte[] Decompress(byte[] bytes)
        {
            using (var compressStream = new MemoryStream(bytes))
            {
                using (var zipStream = new GZipStream(compressStream, CompressionMode.Decompress))
                {
                    using (var resultStream = new MemoryStream())
                    {
                        zipStream.CopyTo(resultStream);
                        return resultStream.ToArray();
                    }
                }
            }
        }

        /// <summary>
        /// 判断是否为整数
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsInteger(string s)
        {
            string pattern = @"^\d*$";
            return Regex.IsMatch(s, pattern);
        }

        /// <summary>
        /// 判断是否为整数
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static bool IsGoodRatio(string s)
        {
            string pattern = @"^[\d:]+$";
            return Regex.IsMatch(s, pattern);
        }

        public static void Talk(string content)
        {
            try
            {
                speech.SpeakAsync(content);
            }
            catch (Exception)
            {

            }

        }

        #endregion

        #region 业务相关

        public static string[] GetGG(string gg)
        {
            return gg.Split(GetGGSplitter(), StringSplitOptions.RemoveEmptyEntries);
        }

        public static string[] GetGGSplitter()
        {
            return new string[] { ";", "；", ",", "，" };
        }

        public static string[] GetRatioSplitter()
        {
            return new string[] { ":", "："};
        }

        public static int GetTagLevel(string ratio)
        {
            return ratio.Split(GetRatioSplitter(), StringSplitOptions.None).Length;
        }

        /// <summary>
        /// 返回比例数字，比如1:20，则返回 1和20
        /// </summary>
        /// <param name="ratio"></param>
        /// <returns>数组长度等于包装级别</returns>
        public static int[] GetRatios(string ratio)
        {
            string[] ss = ratio.Split(GetRatioSplitter(), StringSplitOptions.None);
            int[] ri = new int[ss.Length];

            for (int i = 0; i < ss.Length; i++)
            {
                ri[i] = Convert.ToInt32(ss[i]);
            }

            return ri;
        }

        /// <summary>
        /// 四级关联的各级包装数量顺序ratio43,ratio32,ratio21,0
        /// 三级关联的各级包装数量顺序ratio32,ratio21,0
        /// 二级关联的各级包装数量顺序ratio21,0
        /// </summary>
        /// <param name="ratio"></param>
        /// <returns>数组长度等于包装级别</returns>
        public static int[] GetLevelRatios(string ratio)
        {
            int[] ri = GetRatios(ratio);

            for (int i = 0; i < ri.Length-1; i++)
            {
                ri[i] = ri[i+1]/ri[i];
            }

            if (ri.Length>1)
            {
                ri[ri.Length - 1] = 0;
            }

            return ri;
        }

        /// <summary>
        /// 获取各工位一级码比例:ratio41, ratio31, ration21
        /// </summary>
        /// <param name="station"></param>
        /// <param name="ratio"></param>
        /// <returns></returns>
        public static int GetStationRatio(int station, string ratio)
        {
            int[] ri = GetLevelRatios(ratio);

            switch (station)
            {
                case 1:
                    return 1;
                case 2:
                    return ri[ri.Length-2];
                case 3:
                    return ri[ri.Length - 3] * ri[ri.Length - 2];
                case 4:
                    return ri[0] * ri[1] * ri[2];
                default:
                    return 1;
            }
        }

        /// <summary>
        /// 获取各工位顶级码比例:ratio43, ratio42, ration41; ratio32,ratio31
        /// </summary>
        /// <param name="station"></param>
        /// <param name="ratio"></param>
        /// <returns></returns>
        public static int GetStationRatio2(int station, string ratio)
        {
            int[] ri = GetRatios(ratio);

            return ri[ri.Length-station];
        }

        /// <summary>
        /// 从原始码获取24位数据
        /// </summary>
        /// <param name="code"></param>
        /// <param name="orgCode"></param>
        /// <param name="level">码级别，如果不无法确认，则写1，相当于与一级码保持一致。。。特殊产品的一级码可能无产品或文号</param>
        /// <returns></returns>
        public static bool SYZSGet24BitFromCode(ref string code, string orgCode, int level)
        {
	        if (SYZSCheckProduct(orgCode, level))
	        {
		        if (SYZSCheck24Bit(orgCode))
		        {
                    code = SYZSGet24Bit(orgCode);
                    return true;
		        }
		        else
		        {
                    code = ("不是有效的24位数字");
			        return false;
		        }
		
	        }
	        else
	        {
                code = ("产品名称或者批准文号不一致");
		        return false;
	        }
        }

        public static string SYZSGet24BitFromCodeNoCheck(string orgCode)
        {

            if (string.IsNullOrEmpty(orgCode))
            {
                return "";
            }

            if (SYZSCheck24Bit(orgCode))
            {
                return SYZSGet24Bit(orgCode);
            }
            else
            {
                return "";
            }

        }

        public static bool SYZSCheck24Bit(string code)
        {

            if (string.IsNullOrEmpty(CodePrcUtility.CODEREG))
            {
                return true;
            }
            else
            {
                return ValidateHelper.IsMatch(code, CodePrcUtility.CODEREG);
            }
        }

        private static string SYZSGet24Bit(string code)
        {
            if (string.IsNullOrEmpty(CodePrcUtility.CODEREG))
            {
                return code;
            }
            else
            {
                return ValidateHelper.Match(code, CodePrcUtility.CODEREG);
            }
            
        }

        public static string SYZSSet24Bit(string code, string Bit24)
        {
            string s = ValidateHelper.Match(code, CodePrcUtility.CODEREG);
            return code.Replace(s, Bit24);
        }

        public static string SYZSGetTym(string code)
        {
            string codeReg = ConfigurationHelper.AppGetString("codeReg");
            codeReg = Regex.Replace(codeReg, @"[^0-9]+", "");

            int codeLen = Convert.ToInt32(codeReg);
            if (string.IsNullOrEmpty(code))
            {
                return "";
            }

            if (code.Length<=codeLen)
            {
                return code;
            }


            string[] items = code.Split(new string[] { ",", "，" }, StringSplitOptions.RemoveEmptyEntries);

            if (items.Length>=5)
            {
                int idx1 = codeLen + 1;
                int idx2 = code.IndexOf(items[items.Length-3]);
                idx2--;

                return code.Substring(idx1, idx2 - idx1);
            }
            else
            {
                return code;
            }
        }

        public static string SYZSGetPZWH(string code)
        {
            string codeLen = ConfigurationHelper.AppGetString("codeReg");
            codeLen = Regex.Replace(codeLen, @"[^0-9]+", "");

            if (string.IsNullOrEmpty(code))
            {
                return "";
            }

            if (code.Length <= Convert.ToInt32(codeLen))
            {
                return code;
            }

            string[] items = code.Split(new string[] { ",", "，" }, StringSplitOptions.RemoveEmptyEntries);

            if (items.Length >= 5)
            {
                return items[items.Length - 3];
            }
            else
            {
                return code;
            }
        }

        /// <summary>
        /// 检测品名和文号
        /// </summary>
        /// <param name="code">原始码</param>
        /// <param name="level">码级别，如果不无法确认，则写1，相当于与一级码保持一致。。。特殊产品的一级码可能无产品或文号</param>
        /// <returns></returns>
        public static bool SYZSCheckProduct(string code, int level)
        {
            bool chk = true;
            if (level>1)
            {
                chk = CodePrcUtility.PRODUCT_CHECK;
            }
            else
            {
                chk = CodePrcUtility.PRODUCT_CHECKLevel1;
            }

            if (chk)
            {
                string curProduct = PublicObject.CurTask.tym.Replace("(", "（").Replace(")", "）").Replace(",", "，");//英文字符替换为中文字符
                string curPZWH = PublicObject.CurTask.pzwh.Replace("(", "（").Replace(")", "）").Replace(",", "，");

                code = code.Replace("(", "（").Replace(")", "）").Replace(",", "，");
                if (code.Contains(curProduct) && code.Contains(curPZWH))
                {
                    return true;
                }
                else
                {
                    if (level == 1)
                    {//一级码可能只包含品名或文号
                        if (code.Contains(curProduct) || code.Contains(curPZWH))
                        {
                            return true;
                        }
                    }

                    return false;
                }
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 通过生产日期获取有效期
        /// </summary>
        /// <param name="scrq">生产日期</param>
        /// <param name="yxqdw">有效期单位</param>
        /// <param name="yxq">有效期</param>
        /// <returns></returns>
        public static DateTime SYZSGetYXQ(DateTime scrq, date_unit yxqdw, int yxq)
        {
            DateTime dtNow = scrq;
            switch (yxqdw)
            {
                case date_unit.DU_YEAR:
                    dtNow = dtNow.AddYears(yxq);
                    dtNow = dtNow.AddDays(-1);
                    break;
                case date_unit.DU_MONTH:
                    dtNow = dtNow.AddMonths(yxq);
                    dtNow = dtNow.AddDays(-1);
                    break;
                case date_unit.DU_DAY:
                    dtNow = dtNow.AddDays(yxq);
                    dtNow = dtNow.AddDays(-1);
                    break;
                case date_unit.DU_HOUR:
                    dtNow = dtNow.AddHours(yxq);
                    break;
                case date_unit.DU_MINUTE:
                    dtNow = dtNow.AddMinutes(yxq);
                    break;
                case date_unit.DU_SECOND:
                    dtNow = dtNow.AddSeconds(yxq);
                    break;
                default:
                    dtNow = dtNow.AddMonths(yxq);
                    break;
            }

            return dtNow;
        }

        #endregion


    }
}
